﻿using Vowei.Core.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using Vowei.Data;
using Vowei.Data.Models;
using Vowei.Web.Models;
using System.Collections;

namespace vowei.test
{
    /// <summary>
    ///This is a test class for TaskTest and is intended
    ///to contain all TaskTest Unit Tests
    ///</summary>
    [TestClass]
    public class TaskTest : TestBase
    {
        [TestMethod()]
        public void CloseTest()
        {
            Task target = new Task();
            VoweiContext.TicketStatusManager.Close(target);

            Assert.AreEqual(1.0f, target.Progress);
            Assert.IsNotNull(target.ClosedDate);
        }
        
        [TestMethod]
        public void AssociateMultipleMilestonesProjectTest()
        {
            var project = new Project()
            {
                Title = "AssociateMultipleMilestonesProjectTest_Project",
                Owner = Setting.DefaultUserName
            };
            
            for (int i = 0; i < 10; ++i)
            {
                var milestone = new Milestone()
                {
                    Title = "AssociateMilestoneProjectTest_Milestone"
                };
                project.Children.Add(milestone);
            }

            using (var context = new VoweiContextImpl())
            {
                context.Projects.Add(project);
                foreach (Milestone milestone in project.Children )
                    context.Milestones.Add(milestone);
                context.SaveChanges();
            }
        }

        [TestMethod]
        public void DailyRecursiveTaskEveryDayBasicTest()
        {
            var project = CreateProjectHelper("DailyRecursiveTaskEveryDayBasicTest");
            project.StartDate = DateTime.Now;
            project.DueDate = project.StartDate + TimeSpan.FromDays(30);
            var expected = CreateTaskHelper("DailyRecursiveTaskEveryDayBasicTest", (Project)project);
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            // 指明每两天重复一次
            setting.EveryDays(2);
            setting.Task = expected;
            
            Assert.AreEqual(RecurrencePattern.Daily, setting.Pattern);
            Assert.IsNotNull(setting.RecursiveEndDate);
            Assert.AreEqual(expected.DueDate, setting.RecursiveEndDate.Value);

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);
            Assert.IsNotNull(actual);
            Assert.AreEqual(RecurrencePattern.Daily, actual.Pattern);

            Assert.IsTrue(actual.HasOccurrence(DateTime.Now));
            Assert.IsFalse(actual.HasOccurrence(DateTime.Now + TimeSpan.FromDays(1)));
            Assert.IsTrue(actual.HasOccurrence(DateTime.Now + TimeSpan.FromDays(2)));
            Assert.IsTrue(actual.HasOccurrence(project.DueDate.Value));
            Assert.IsFalse(actual.HasOccurrence(project.DueDate.Value + TimeSpan.FromDays(1)));
            Assert.IsFalse(actual.HasOccurrence(project.DueDate.Value + TimeSpan.FromDays(2)));
        }

        [TestMethod]
        public void DailyRecursiveTaskEveryDayNoEndDateBasicTest()
        {
            var project = CreateProjectHelper("DailyRecursiveTaskEveryDayNoEndDateBasicTest");
            project.StartDate = DateTime.Now;
            project.DueDate = null;
            var expected = CreateTaskHelper("DailyRecursiveTaskEveryDayNoEndDateBasicTest", (Project)project);
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            // 指明每两天重复一次
            setting.EveryDays(2);
            setting.Task = expected;

            Assert.AreEqual(RecurrencePattern.Daily, setting.Pattern);
            Assert.IsNull(setting.RecursiveEndDate);

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);
            Assert.IsNotNull(actual);
            Assert.AreEqual(RecurrencePattern.Daily, actual.Pattern);

            Assert.IsTrue(actual.HasOccurrence(DateTime.Now));
            Assert.IsFalse(actual.HasOccurrence(DateTime.Now + TimeSpan.FromDays(1)));
            Assert.IsTrue(actual.HasOccurrence(DateTime.Now + TimeSpan.FromDays(2)));
            Assert.IsFalse(actual.HasOccurrence(DateTime.Now + TimeSpan.FromDays(365)));
            Assert.IsTrue(actual.HasOccurrence(DateTime.Now + TimeSpan.FromDays(366)));
        }

        [TestMethod]
        public void DailyRecursiveTaskEveryWeekDayBasicTest()
        {
            var project = CreateProjectHelper("DailyRecursiveTaskEveryWeekDayBasicTest");
            // Tuesday
            project.StartDate = new DateTime(2011, 3, 22);
            project.DueDate = project.StartDate + TimeSpan.FromDays(365);
            var expected = CreateTaskHelper("DailyRecursiveTaskEveryWeekDayBasicTest", (Project)project);
            expected.DueDate = project.DueDate;
            expected.StartDate = project.StartDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.OnAllWeekDays();
            setting.Task = expected;
            Assert.AreEqual(RecurrencePattern.Daily, setting.Pattern);
            Assert.IsNotNull(setting.RecursiveEndDate);
            Assert.AreEqual(expected.DueDate, setting.RecursiveEndDate.Value);

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);
            Assert.IsNotNull(actual);
            Assert.AreEqual(RecurrencePattern.Daily, actual.Pattern);

            Assert.IsFalse(actual.HasOccurrence(expected.StartDate.Value - TimeSpan.FromDays(1)));
            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 3, 25)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 26)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 3, 17)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 3, 16)));
            Assert.IsTrue(actual.HasOccurrence(project.DueDate.Value));
            Assert.IsFalse(actual.HasOccurrence(project.DueDate.Value + TimeSpan.FromDays(1)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2013, 3, 25)));
        }

        [TestMethod]
        public void WeeklyRecursiveTaskBasicTest()
        {
            var project = CreateProjectHelper("WeeklyRecursiveTaskBasicTest");
            // Tuesday
            project.StartDate = new DateTime(2011, 3, 22);
            project.DueDate = new DateTime(2012, 3, 31);
            var expected = CreateTaskHelper("WeeklyRecursiveTaskBasicTest", (Project)project);
            expected.StartDate = project.StartDate;
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.Pattern = RecurrencePattern.Weekly;
            setting.EveryWeeks(1).OnWeekDays(
                DayOfWeek.Monday,
                DayOfWeek.Wednesday,
                DayOfWeek.Friday,
                DayOfWeek.Saturday);
            setting.Task = expected;
            Assert.AreEqual(RecurrencePattern.Weekly, setting.Pattern);
            Assert.IsNotNull(setting.RecursiveEndDate);
            Assert.AreEqual(expected.DueDate, setting.RecursiveEndDate.Value);

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);
            Assert.IsNotNull(actual);
            Assert.AreEqual(RecurrencePattern.Weekly, actual.Pattern);

            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 24)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 3, 25)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 3, 26)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 27)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 3, 28)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 29)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 3, 17)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 3, 16)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 3, 15)));
            Assert.IsTrue(actual.HasOccurrence(project.DueDate.Value));
            Assert.IsFalse(actual.HasOccurrence(project.DueDate.Value + TimeSpan.FromDays(1)));
        }

        [TestMethod]
        public void WeeklyRecursiveTaskEvery2WeekTest()
        {
            var project = CreateProjectHelper("WeeklyRecursiveTaskEvery2WeekTest");
            // Tuesday
            project.StartDate = new DateTime(2011, 3, 22);
            project.DueDate = new DateTime(2012, 3, 31);
            var expected = CreateTaskHelper("WeeklyRecursiveTaskEvery2WeekTest", (Project)project);
            expected.StartDate = project.StartDate;
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.Pattern = RecurrencePattern.Weekly;
            setting.EveryWeeks(2).OnWeekDays(
                DayOfWeek.Monday, DayOfWeek.Thursday, DayOfWeek.Friday);

            setting.Task = expected;
            Assert.AreEqual(RecurrencePattern.Weekly, setting.Pattern);
            Assert.IsNotNull(setting.RecursiveEndDate);
            Assert.AreEqual(expected.DueDate, setting.RecursiveEndDate.Value);

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);
            Assert.IsNotNull(actual);
            Assert.AreEqual(RecurrencePattern.Weekly, actual.Pattern);
            
            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 23)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 3, 24)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 3, 25)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 26)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 27)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 28)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 29)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 30)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 31)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 4, 1)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 4, 3)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 4, 4)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 4, 5)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 4, 6)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 4, 7)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 3, 17)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 3, 16)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 3, 15)));
            Assert.IsFalse(actual.HasOccurrence(project.DueDate.Value));
            Assert.IsFalse(actual.HasOccurrence(project.DueDate.Value + TimeSpan.FromDays(1)));
        }

        [TestMethod]
        public void MonthlyRecursiveTaskBasicTest()
        {
            var project = CreateProjectHelper("MonthlyRecursiveTaskBasicTest");
            // Tuesday
            project.StartDate = new DateTime(2011, 3, 22);
            project.DueDate = new DateTime(2012, 3, 31);
            var expected = CreateTaskHelper("MonthlyRecursiveTaskBasicTest", (Project)project);
            expected.StartDate = project.StartDate;
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.Pattern = RecurrencePattern.Monthly;

            // day 22 of every 1 month(s)
            setting.EveryMonths(1).OnDay(22);

            setting.Task = expected;
            Assert.AreEqual(RecurrencePattern.Monthly, setting.Pattern);
            Assert.IsNotNull(setting.RecursiveEndDate);
            Assert.AreEqual(expected.DueDate, setting.RecursiveEndDate.Value);

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);
            Assert.IsNotNull(actual);
            Assert.AreEqual(RecurrencePattern.Monthly, actual.Pattern);

            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 4, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 4, 1)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 1, 22)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 3, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 5, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 4, 23)));
        }

        [TestMethod]
        public void MonthlyRecursiveTaskEveryWeekTest()
        {
            var project = CreateProjectHelper("MonthlyRecursiveTaskEveryWeekTest");
            // Tuesday
            project.StartDate = new DateTime(2011, 3, 22);
            project.DueDate = new DateTime(2012, 3, 31);
            var expected = CreateTaskHelper("MonthlyRecursiveTaskEveryWeekTest", (Project)project);
            expected.StartDate = project.StartDate;
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.Pattern = RecurrencePattern.Monthly;

            // The 4th tuesday of every 1 months
            setting.EveryMonths(1).EveryWeeks(4).OnWeekDays(DayOfWeek.Tuesday);

            setting.Task = expected;
            Assert.AreEqual(RecurrencePattern.Monthly, setting.Pattern);
            Assert.IsNotNull(setting.RecursiveEndDate);
            Assert.AreEqual(expected.DueDate, setting.RecursiveEndDate.Value);

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);
            Assert.IsNotNull(actual);
            Assert.AreEqual(RecurrencePattern.Monthly, actual.Pattern);

            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2011, 4, 19)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 4, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 4, 1)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 1, 22)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 1, 24)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 3, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 5, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 4, 23)));
        }

        [TestMethod]
        public void YearlyRecursiveTaskEveryYearBasicTest()
        {
            var project = CreateProjectHelper("YearlyRecursiveTaskEveryYearBasicTest");
            // Wednesday
            project.StartDate = new DateTime(2011, 3, 23);
            project.DueDate = new DateTime(2022, 3, 31);
            var expected = CreateTaskHelper("YearlyRecursiveTaskEveryYearBasicTest", (Project)project);
            expected.StartDate = project.StartDate;
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.Pattern = RecurrencePattern.Yearly;

            setting.EveryYears(1);
            setting.Task = expected;

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);

            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 24)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 3, 23)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2022, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2023, 3, 23)));
        }

        [TestMethod]
        public void YearlyRecursiveTaskEveryTwoYearBasicTest()
        {
            var project = CreateProjectHelper("YearlyRecursiveTaskEveryTwoYearBasicTest");
            // Wednesday
            project.StartDate = new DateTime(2011, 3, 23);
            project.DueDate = new DateTime(2022, 3, 31);
            var expected = CreateTaskHelper("YearlyRecursiveTaskEveryTwoYearBasicTest", (Project)project);
            expected.StartDate = project.StartDate;
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.Pattern = RecurrencePattern.Yearly;

            setting.EveryYears(2);
            setting.Task = expected;

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);

            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 24)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 3, 23)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2013, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2022, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2023, 3, 23)));
        }

        [TestMethod]
        public void YearlyRecursiveTaskEveryYearMonthWeekTest()
        {
            var project = CreateProjectHelper("YearlyRecursiveTaskEveryYearMonthWeekTest");
            // Wednesday
            project.StartDate = new DateTime(2011, 3, 23);
            project.DueDate = new DateTime(2022, 3, 31);
            var expected = CreateTaskHelper("YearlyRecursiveTaskEveryYearMonthWeekTest", (Project)project);
            expected.StartDate = project.StartDate;
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.Pattern = RecurrencePattern.Yearly;

            setting.EveryYears(1).OnMonth(3).OnDay(23);
            setting.Task = expected;

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);

            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 24)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 3, 23)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2022, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2023, 3, 23)));
        }

        [TestMethod]
        public void YearlyRecursiveTaskEveryYearMonthWeekDayTest()
        {
            var project = CreateProjectHelper("YearlyRecursiveTaskEveryYearMonthWeekDayTest");
            // Wednesday
            project.StartDate = new DateTime(2011, 3, 23);
            project.DueDate = new DateTime(2022, 3, 31);
            var expected = CreateTaskHelper("YearlyRecursiveTaskEveryYearMonthWeekDayTest", (Project)project);
            expected.StartDate = project.StartDate;
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.Pattern = RecurrencePattern.Yearly;

            // Recur every 1 year on the 4th Wednesday of March
            setting.EveryYears(1).EveryWeeks(4).OnWeekDays(DayOfWeek.Wednesday).OnMonth(3);
            setting.Task = expected;

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);

            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 24)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 3, 21)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2021, 3, 23)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2022, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2023, 3, 23)));
        }

        [TestMethod]
        public void YearlyRecursiveTaskEveryYearMonthWeekDayAnotherTest()
        {
            var project = CreateProjectHelper("YearlyRecursiveTaskEveryYearMonthWeekDayAnotherTest");
            // Wednesday
            project.StartDate = new DateTime(2011, 3, 23);
            project.DueDate = new DateTime(2022, 3, 31);
            var expected = CreateTaskHelper("YearlyRecursiveTaskEveryYearMonthWeekDayAnotherTest", (Project)project);
            expected.StartDate = project.StartDate;
            expected.DueDate = project.DueDate;
            var setting = new RecurrenceSetting(expected.StartDate.Value);
            setting.Pattern = RecurrencePattern.Yearly;

            // Recur every 1 year on the 4th Wednesday of March
            setting.EveryYears(1).OnMonth(3).EveryWeeks(4).OnWeekDays(DayOfWeek.Wednesday);
            setting.Task = expected;

            VoweiContext.Tasks.Add(expected);
            VoweiContext.SaveChanges();

            var actual = VoweiContext.RecurrenceSettings.Find(setting.ID);

            Assert.IsTrue(actual.HasOccurrence(expected.StartDate.Value));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 22)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2011, 3, 24)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2012, 3, 21)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2012, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2021, 3, 23)));
            Assert.IsTrue(actual.HasOccurrence(new DateTime(2022, 3, 23)));
            Assert.IsFalse(actual.HasOccurrence(new DateTime(2023, 3, 23)));
        }

        [TestMethod]
        public void RecurrenceSettingsDesignTest()
        {
            // every 1 day(s)
            var setting = new RecurrenceSetting(DateTime.Now);
            setting.Pattern = RecurrencePattern.Daily;
            setting.EveryDays(1);

            Assert.AreEqual(RecurrencePattern.Daily, setting.Pattern);
            Assert.AreEqual(1, setting.DayOccurrence);
            Assert.AreEqual(0, setting.YearOccurrence);
            Assert.AreEqual(0, setting.MonthOccurrence);
            Assert.AreEqual(0, setting.WeekOccurrence);

            // every weekdays
            setting = new RecurrenceSetting(DateTime.Now);
            setting.Pattern = RecurrencePattern.Daily;
            setting.OnAllWeekDays();

            Assert.AreEqual(RecurrencePattern.Daily, setting.Pattern);
            Assert.AreEqual(0, setting.DayOccurrence);
            Assert.AreEqual(0, setting.YearOccurrence);
            Assert.AreEqual(0, setting.MonthOccurrence);
            Assert.AreEqual(1, setting.WeekOccurrence);

            // recur evey 1 weeks on Sunday
            setting = new RecurrenceSetting(DateTime.Now);
            setting.Pattern = RecurrencePattern.Weekly;
            setting.EveryWeeks(1).OnWeekDays(DayOfWeek.Sunday);

            Assert.AreEqual(RecurrencePattern.Weekly, setting.Pattern);
            Assert.AreEqual(0, setting.DayOccurrence);
            Assert.AreEqual(0, setting.YearOccurrence);
            Assert.AreEqual(0, setting.MonthOccurrence);
            Assert.AreEqual(1, setting.WeekOccurrence);
            Assert.IsTrue(setting.RecurWeekDays[(int)DayOfWeek.Sunday]);

            for (int i = (int)DayOfWeek.Monday; i < setting.RecurWeekDays.Length; ++i)
                Assert.IsFalse(setting.RecurWeekDays[i]);

            // recur every 2 weeks on Sunday, Monday
            setting = new RecurrenceSetting(DateTime.Now);
            setting.Pattern = RecurrencePattern.Weekly;
            setting.EveryWeeks(2).OnWeekDays(DayOfWeek.Sunday, DayOfWeek.Monday);
            Assert.AreEqual(RecurrencePattern.Weekly, setting.Pattern);
            Assert.AreEqual(0, setting.DayOccurrence);
            Assert.AreEqual(0, setting.YearOccurrence);
            Assert.AreEqual(0, setting.MonthOccurrence);
            Assert.AreEqual(2, setting.WeekOccurrence);
            Assert.IsTrue(setting.RecurWeekDays[(int)DayOfWeek.Sunday]);
            Assert.IsTrue(setting.RecurWeekDays[(int)DayOfWeek.Monday]);

            for (int i = (int)DayOfWeek.Tuesday; i < setting.RecurWeekDays.Length; ++i)
                Assert.IsFalse(setting.RecurWeekDays[i]);

            // recur day 22 of every 1 months
            setting = new RecurrenceSetting(DateTime.Now);
            setting.Pattern = RecurrencePattern.Monthly;
            setting.EveryMonths(1).OnDay(22);
            Assert.AreEqual(RecurrencePattern.Monthly, setting.Pattern);
            Assert.AreEqual(0, setting.DayOccurrence);
            Assert.AreEqual(0, setting.YearOccurrence);
            Assert.AreEqual(1, setting.MonthOccurrence);
            Assert.AreEqual(0, setting.WeekOccurrence);
            Assert.AreEqual(22, setting.RecurDay);

            // recur the fourth Tuesday of every 1 months
            setting = new RecurrenceSetting(DateTime.Now);
            setting.Pattern = RecurrencePattern.Monthly;
            setting.EveryMonths(1).EveryWeeks(4).OnWeekDays(DayOfWeek.Tuesday);
            Assert.AreEqual(RecurrencePattern.Monthly, setting.Pattern);
            Assert.AreEqual(0, setting.DayOccurrence);
            Assert.AreEqual(0, setting.YearOccurrence);
            Assert.AreEqual(1, setting.MonthOccurrence);
            Assert.AreEqual(4, setting.WeekOccurrence);
            Assert.IsTrue(setting.RecurWeekDays[(int)DayOfWeek.Tuesday]);
            Assert.IsFalse(setting.RecurWeekDays[(int)DayOfWeek.Sunday]);
            Assert.IsFalse(setting.RecurWeekDays[(int)DayOfWeek.Monday]);
            for (int i = (int)DayOfWeek.Wednesday; i < setting.RecurWeekDays.Length; ++i)
                Assert.IsFalse(setting.RecurWeekDays[i]);

            // recur every 1 years on March 22
            setting = new RecurrenceSetting(DateTime.Now);
            setting.Pattern = RecurrencePattern.Yearly;
            setting.EveryYears(1).OnMonth(3).OnDay(22);
            Assert.AreEqual(RecurrencePattern.Yearly, setting.Pattern);
            Assert.AreEqual(0, setting.DayOccurrence);
            Assert.AreEqual(1, setting.YearOccurrence);
            Assert.AreEqual(0, setting.MonthOccurrence);
            Assert.AreEqual(0, setting.WeekOccurrence);
            Assert.AreEqual(3, setting.RecurMonth);
            Assert.AreEqual(22, setting.RecurDay);

            // recur every 2 years on the fourth Tuesday of March
            setting = new RecurrenceSetting(DateTime.Now);
            setting.Pattern = RecurrencePattern.Yearly;
            setting.EveryYears(2).OnMonth(3).EveryWeeks(4).OnWeekDays(DayOfWeek.Tuesday);
            Assert.AreEqual(RecurrencePattern.Yearly, setting.Pattern);
            Assert.AreEqual(0, setting.DayOccurrence);
            Assert.AreEqual(2, setting.YearOccurrence);
            Assert.AreEqual(0, setting.MonthOccurrence);
            Assert.AreEqual(4, setting.WeekOccurrence);
            Assert.AreEqual(3, setting.RecurMonth);
            Assert.AreEqual(0, setting.RecurDay);
            Assert.IsTrue(setting.RecurWeekDays[(int)DayOfWeek.Tuesday]);
        }

        [TestMethod]
        public void RecurrenceTaskExceptionConceptDesignTest()
        {
            // every 1 day(s)
            var setting = new RecurrenceSetting(new DateTime(2011, 3, 23));
            setting.Pattern = RecurrencePattern.Daily;
            setting.EveryDays(1);

            // with 1 exception
            var exceptionDate = new DateTime(2011, 3, 30);
            Assert.IsTrue(setting.HasOccurrence(exceptionDate));
            setting.DeleteOccurrencyAt(exceptionDate);
            Assert.IsFalse(setting.HasOccurrence(exceptionDate));

            // every 2 day(s)
            setting = new RecurrenceSetting(new DateTime(2011, 3, 23));
            setting.Pattern = RecurrencePattern.Daily;
            setting.EveryDays(2);

            exceptionDate = new DateTime(2011, 3, 26);
            Assert.IsFalse(setting.HasOccurrence(exceptionDate));
            setting.AddException(exceptionDate);
            Assert.IsTrue(setting.HasOccurrence(exceptionDate));
        }
    }
}
